package com.example.teesystem.controller;

import cn.hutool.core.lang.Validator;
import cn.hutool.json.JSONUtil;
import com.example.teesystem.common.cache.UserCache;
import com.example.teesystem.common.exception.CustomException;
import com.example.teesystem.common.utils.*;
import com.example.teesystem.entity.User;
import com.example.teesystem.entity.vo.user.UserSelectVo;
import com.example.teesystem.entity.vo.user.UserSelectVo2;
import com.example.teesystem.entityDto.UserDto;
import com.example.teesystem.filter.MyHandlerInterceptor;
import com.example.teesystem.service.UserService;

import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.*;

import static com.example.teesystem.common.utils.FileUtil.SUFFIX;

/**
 * @author pxr
 * @data 2022/3/23 9:53
 */

@RestController
@RequestMapping(value = "/tee/user" , produces = "application/json; charset=utf-8" )
@RequiredArgsConstructor
public class UserController {
    private final UserService userService;
    private final HttpServletRequest request;

    /**
     * 注册
     * @param user
     * @return
     */
    @PostMapping(value = "register")
    public Response register(@RequestBody User user){//注册
        return userService.register(user);
    }

    /**
     * 获取盐
     * @param map
     * @return
     */
    @PostMapping(value = "getSalt")
    public Response getSalt(@RequestBody Map<String,String> map){//获取盐
        int uid;
        String account = map.get("account");

        Validator.validateNotNull(account, ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        
        uid = userService.getUIdByAccount(account);
        System.out.println(IPUtil.getIpAddr(request));

        if(uid == -1){
            throw new CustomException(ResultCode.NO_USER.getMsg(), ResultCode.NO_USER.getCode());
        }else{
            if(UserCache.userMap.get(uid).getAccountType()==1){
                throw new CustomException(ResultCode.ACCOUNT_LOCK.getMsg(), ResultCode.ACCOUNT_LOCK.getCode());
            }
            return Response.ok(JSONUtil.createObj().putOnce("salt", userService.getSaltByUid(uid)));
        }
    }

    /**
     * 登陆
     * @param map
     * @return
     */
    @PostMapping(value = "login")
    public Response login(@RequestBody Map<String,String> map){//登陆
        String account = map.get("account"),password = map.get("password");

        if(Validator.isNull(account)||Validator.isNull(password))//参数验证
        {
            throw new CustomException(ResultCode.PARAMETER_MISS.getMsg(),ResultCode.PARAMETER_MISS.getCode());
        }

        int uid = userService.getUIdByAccount(account);
        if(!userService.login(uid,password)){
            throw new CustomException(ResultCode.PASSWORD_ERROR.getMsg(),ResultCode.PASSWORD_ERROR.getCode());
        }
        userService.loginSuccess(uid);
        System.out.println("*****" + uid + "*****\n");
        User user = UserCache.userMap.get(uid);
        String token = userService.getToken(user);
        UserDto userDto = new UserDto(user,token);
        return Response.ok(userDto);
    }

    /**
     * 登出
     * @return
     */
    @PostMapping(value = "logout")
    public Response logout(){//登出
        int uid = MyHandlerInterceptor.getUid();
        userService.logout(uid);
        return Response.ok();
    }

    /**
     * 获取个人信息
     * @return
     */
    @PostMapping(value = "/getMyMessage")
    public Response getMyMessage(){
        User user = UserCache.userMap.get(MyHandlerInterceptor.getUid());
        UserDto userDto = new UserDto(user,"");
        return Response.ok(userDto);
    }

    /**
     * 更新个人信息
     * @param map
     * @return
     */
    @PostMapping(value = "/updateMyMessage")
    public Response updateMyMessage(@RequestBody Map<String,String> map){//更新个人信息
        String username,gender,birth,name,academy,mail;
        Integer grade = 0,classes = 0;
        Date birthday;
        try{
            username = map.get("username");
            gender = map.get("gender");
            birth = map.get("birthday");
            try{
                birthday = TimeUtil.stringToDate(birth);
            }catch (Exception e){
                return Response.error(ResultCode.PARAM_CONVERT_FAIL.getMsg(), ResultCode.PARAM_CONVERT_FAIL.getCode());
            }
            name = map.get("myName");
            academy = map.get("academy");
            mail = map.get("mail");
        }catch (Exception e){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        if(UserCache.userMap.get(MyHandlerInterceptor.getUid()).getType()==2){
            try{
                grade = Integer.parseInt(map.get("grade"));
                classes = Integer.parseInt(map.get("classes"));
            }catch (Exception e){
                return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
            }
        }
        return userService.updateMyMessage(username,gender,birthday,name,academy,grade,classes,mail,MyHandlerInterceptor.getUid());
    }

    /**
     * 更改密码
     * @param map
     * @return
     */
    @PostMapping(value = "/updatePassword")
    public Response updatePassword(@RequestBody Map<String,String> map){
        String oldPassword = map.get("oldPassword"),newPassword = map.get("newPassword");
        if(Validator.isNull(oldPassword)&&Validator.isNotNull(newPassword)){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        return userService.updatePassword(oldPassword,newPassword);
    }

    /**
     * 管理员分页获取用户
     * @param userSelectVo
     * @return
     */
    @PostMapping(value = "/getUser")
    public Response getUser(@Valid @RequestBody UserSelectVo userSelectVo){
       if(!PermissionUtil.isManager()) {
           return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
       }
       try{
           return Response.ok(userService.getUser(userSelectVo));
       }catch (Exception e){
           return Response.error(ResultCode.GET_ERROR.getMsg(), ResultCode.GET_ERROR.getCode());
       }
    }

    /**
     * 管理员通过id获取用户个人信息
     * @param map
     * @return
     */
    @PostMapping(value = "/getUserMessageById")
    public Response getUserMessageById(@RequestBody Map<String,String> map){
        if(!PermissionUtil.isManager()) {
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        int id;
        try {
            id = Integer.parseInt(map.get("id"));
        }catch (Exception e){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        return userService.getUserMsg(id);
    }

    /**
     * 依据检索信息获取用户
     * @param userSelectVo2
     * @return
     */
    @PostMapping(value = "/getUserByMessage")
    public Response getUserByMessage(@Valid @RequestBody UserSelectVo2 userSelectVo2){
        if(userSelectVo2.getAcademy() == null && userSelectVo2.getAccount() == null && userSelectVo2.getMyName() == null) {
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        return userService.getUserByMsg(userSelectVo2);
    }

    /**
     * 管理员更新用户帐号状态
     * @param map
     * @return
     */
    @PostMapping(value = "/updateUserAccountType")
    public Response updateUserAccountType(@RequestBody Map<String,Integer> map){
        if(!PermissionUtil.isManager()){
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        Integer uid = map.get("uid"), accountType = map.get("accountType");
        return userService.updateUserAccountType(uid,accountType);
    }

    /**
     * 管理员更改用户密码
     * @param map
     * @return
     */
    @PostMapping(value = "/updateUserPassword")
    public Response updateUserPassword(@RequestBody Map<String,String> map){
        if(!PermissionUtil.isManager()){
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        int uid;
        String password;
        try{
           uid = Integer.parseInt(map.get("uid"));
           password = map.get("password");
        }catch (Exception e){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        return userService.updateUserPassword(uid,password);
    }

    @PostMapping(value = "/test")
    public Response test(){//开发测试
        return Response.ok();
    }

    /**
     * 通过账户获取个人信息
     * @param map
     * @return
     */
    @PostMapping(value = "/getIdByAccount")
    public Response getIdByAccount(@RequestBody Map<String,List<String>> map){
        if(map.get("account") == null) {
            return Response.error(ResultCode.PARAMETER_ERROR);
        }
        return userService.getUidByAccount(map.get("account"));
    }

    @PostMapping(value = "/getEstimateByStudentId")
    public Response getEstimateByStudentId(@RequestBody(required = false) Map<String, Integer> map){
        int studentId;
        if(map.get("studentId") == null) {
            studentId = MyHandlerInterceptor.getUid();
        } else {
            studentId = map.get("studentId");
        }
        if(UserCache.userMap.get(studentId).getType() == 2){
            return userService.getEstimateOfStudent(studentId);
        }
        else {
            return Response.error(ResultCode.USER_TYPE_NOT_STUDENT_ERROR.getMsg(),ResultCode.USER_TYPE_NOT_STUDENT_ERROR.getCode());
        }
    }

    @PostMapping(value = "/getStudentEstimateByCourseIds")
    public Response getStudentEstimateByCourses(@RequestBody Map<String, Integer> map){
        int studentId;
        if(map.get("studentId") == null) {
            studentId = MyHandlerInterceptor.getUid();
        } else {
            studentId = map.get("studentId");
        }
        if(UserCache.userMap.get(studentId).getType() == 2){
            return userService.GetStudentEstimateByCourses(studentId);
        }
        else {
            return Response.error(ResultCode.USER_TYPE_NOT_STUDENT_ERROR.getMsg(),ResultCode.USER_TYPE_NOT_STUDENT_ERROR.getCode());
        }
    }

    @PostMapping(value = "/updateAvatar")
    @Transactional
    public Response updateAvatar(@RequestParam("file") MultipartFile file){
        if(Validator.isNull(file)) {
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        String fileName = file.getOriginalFilename();
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        boolean contain = false;
        for (int i = 0; i < 6; i++) {
            if (SUFFIX[i].equals(suffixName)) {
                contain = true;
                break;
            }
        }
        if (!contain) {
            throw new CustomException(ResultCode.FILE_ERROR);
        }
        MultipartFile [] files = {file};
        Response response =  FileUtil.UploadFile(files,FileUtil.FILE_PATH+FileUtil.AVATAR);
        if(response.get("data") == null){
            return Response.error(ResultCode.FILE_UPLOAD_ERROR);
        }
        String avatar = (String) ((Map) response.get("data")).get("url");
        try{
            userService.updateAvatar(avatar);
            Map<String,String> map = new HashMap<>();
            map.put("avatar",FileUtil.FILE_PREFIX+avatar);
            return Response.ok(map);
        }catch (Exception e){
            return Response.error(ResultCode.UPDATE_MESSAGE_ERROR);
        }

    }

    @PostMapping(value = "/studentEvaluate")
    public Response studentEvaluate(@RequestBody Map<String,String> map){
        int courseId;
        Date startTime,endTime;
        try{
            courseId = Integer.parseInt(map.get("courseId"));
            startTime = TimeUtil.stringToDate(map.get("startTime"));
            endTime = TimeUtil.stringToDate(map.get("endTime"));
        }catch (Exception e){
            return Response.error(ResultCode.PARAMETER_ERROR);
        }
        return userService.studentEvaluate(courseId,startTime,endTime);
    }

}
